using CSharpX;
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace UnityX
{
    //翻转开关按钮
    [ExecuteAlways]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(CanvasRenderer))]
    [AddComponentMenu("UI/UnityX/OnOffFlip")]
    public class OnOffFlip : MaskableGraphic, IPointerClickHandler
    {
        protected float m_T = 0;
        [SerializeField]
        protected bool m_OnOff = true;
        [SerializeField]
        protected Texture m_OnTexture;
        [SerializeField]
        protected Texture m_OffTexture;

        public bool Interactable = true;
        public Color OnColor = Color.white;
        public Color OffColor = Color.gray;
        public float AnimationSpeed = 4;
        public Action<bool> OnOffEvent;

        public bool OnOff
        {
            get
            {
                return m_OnOff;
            }
            set
            {
                if (m_OnOff != value)
                {
                    m_OnOff = value;
                    SetMaterialDirty();
                    OnOffEvent?.Invoke(value);
                    if (!isActiveAndEnabled)
                    {
                        if (value) m_T = 1;
                        else m_T = 0;
                        SetVerticesDirty();
                    }
                }
            }
        }
        public Texture OnTexture
        {
            get
            {
                return m_OnTexture;
            }
            set
            {
                m_OnTexture = value;
                SetMaterialDirty();
            }
        }
        public Texture OffTexture
        {
            get
            {
                return m_OffTexture;
            }
            set
            {
                m_OffTexture = value;
                SetMaterialDirty();
            }
        }
        public override Texture mainTexture
        {
            get
            {
                Texture texture = m_OnOff ? m_OnTexture : m_OffTexture;
                if (texture == null)
                {
                    if (material != null && material.mainTexture != null)
                    {
                        return material.mainTexture;
                    }
                    return s_WhiteTexture;
                }
                return texture;
            }
        }
        protected void LateUpdate()
        {
            if (m_OnOff)
            {
                if (m_T < 1)
                {
                    m_T += Time.deltaTime * AnimationSpeed;
                    if (m_T > 1)
                    {
                        m_T = 1;
                    }
                    SetVerticesDirty();
                }
            }
            else
            {
                if (m_T > 0)
                {
                    m_T -= Time.deltaTime * AnimationSpeed;
                    if (m_T < 0)
                    {
                        m_T = 0;
                    }
                    SetVerticesDirty();
                }
            }
        }
        public void OnPointerClick(PointerEventData eventData)
        {
            if (!Interactable) return;
            m_OnOff = !m_OnOff;
            SetMaterialDirty();
            OnOffEvent?.Invoke(m_OnOff);
        }
        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();
            Rect rect = GetPixelAdjustedRect();

            Color32 color = Color.Lerp(OffColor, OnColor, m_T);
            Vector4 vector = new Vector4(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
            float v = Curve.SF2(m_T * 2);
            if (m_T < 0.5f)
            {
                v = Curve.SF2(m_T * 2);
                vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.y), color, new Vector2(0f, 0f));
                vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.w), color, new Vector2(0f, 1f));
                vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.w), color, new Vector2(1f, 1f));
                vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.y), color, new Vector2(1f, 0f));

                //vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.y + rect.height * v * 0.15f), color, new Vector2(0f, 0f));
                //vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.w - rect.height * v * 0.15f), color, new Vector2(0f, 1f));
                //vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.w - rect.height * v * 0.15f), color, new Vector2(1f, 1f));
                //vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.y + rect.height * v * 0.15f), color, new Vector2(1f, 0f));
            }
            else
            {
                v = Curve.SF2((1 - m_T) * 2);
                vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.y), color, new Vector2(0f, 0f));
                vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.w), color, new Vector2(0f, 1f));
                vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.w), color, new Vector2(1f, 1f));
                vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.y), color, new Vector2(1f, 0f));

                //vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.y - rect.height * v * 0.15f), color, new Vector2(0f, 0f));
                //vh.AddVert(new Vector3(vector.x + rect.width * v * 0.5f, vector.w + rect.height * v * 0.15f), color, new Vector2(0f, 1f));
                //vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.w + rect.height * v * 0.15f), color, new Vector2(1f, 1f));
                //vh.AddVert(new Vector3(vector.z - rect.width * v * 0.5f, vector.y - rect.height * v * 0.15f), color, new Vector2(1f, 0f));
            }
            vh.AddTriangle(0, 1, 2);
            vh.AddTriangle(2, 3, 0);
        }
    }
}